package com.js.lib.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.springframework.util.StringUtils;
/**
 * 说明：日期工具类
 * 由于SimpleDateFormat非线程安全，采用LocalDateTime来转换
 * @类名: DateUtils
 *
 * @author   kenny
 * @Date	 2020年7月18日下午4:52:26
 */

public class DateUtils {
	private static DateTimeFormatter yyyymmddFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
	private static DateTimeFormatter yyyymmddhhmmssFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	private static DateTimeFormatter yyyymmddhhmmssSSSFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");


	public static Date parse(String dateStr,String pattern) throws DateTimeParseException{
		dateStr = dateStr.replace("/", "-");
		dateStr = dateStr.replaceAll("T"," ").replaceAll("\\+0000","");
		//Pattern = Pattern.toLowerCase();
		/** 是否带时间 */
		if (pattern.indexOf("HH")>-1){
			return asDate(LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern)));
		}else{
			/** 不带时间 */
			return asDate(LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern)));
		}

/*		if (!StringUtils.isEmpty(Pattern)){
			if ("yyyy-mm-dd".equals(Pattern)){
				dateStr = dateStr.substring(0, 10);
				return asDate(LocalDate.parse(dateStr, yyyymmddFormatter));
			}else if ("yyyy-mm-dd hh:mm:ss".equals(Pattern)){
				return asDate(LocalDateTime.parse(dateStr, yyyymmddhhmmssFormatter));
			}else if ("yyyy-mm-dd hh:mm:ss.sss".equals(Pattern)){
				return asDate(LocalDateTime.parse(dateStr, yyyymmddhhmmssSSSFormatter));
			}
		}
		return null;*/
	}

	public static String format(Date date,String pattern){
		/** 是否带时间 */
		if (pattern.indexOf("HH")>-1){
			return DateTimeFormatter.ofPattern(pattern).format(asLocalDateTime(date));
		}else{
			/** 不带时间 */
			return DateTimeFormatter.ofPattern(pattern).format(asLocalDate(date));
		}
		/*if (!StringUtils.isEmpty(Pattern)){
			if ("yyyy-MM-dd".equals(Pattern)){
				return yyyymmddFormatter.format(asLocalDate(date));
			}else if ("yyyy-MM-dd HH:mm:ss".equals(Pattern)){
				return yyyymmddhhmmssFormatter.format(asLocalDate(date));
			}else if ("yyyy-MM-dd HH:mm:ss.SSS".equals(Pattern)){
				return yyyymmddhhmmssSSSFormatter.format(asLocalDate(date));
			}
		}
		return null;*/

	}


	/**
	 * String 转 Date 不带时间
	 * @param dateStr
	 * @return
	 */
	public static Date parseDate(String dateStr) throws DateTimeParseException{
		dateStr = dateStr.replace("/", "-");
		dateStr = dateStr.replaceAll("T"," ").replaceAll("\\+0000","");
		dateStr = dateStr.substring(0, 10);
		return asDate(LocalDate.parse(dateStr, yyyymmddFormatter));
	}
	/**
	 * String 转 DateTime 带时间
	 * @param dateStr
	 * @return
	 */

	public static Date parseDateTime(String dateStr) throws DateTimeParseException{
		dateStr = dateStr.replace("/", "-");
		dateStr = dateStr.replaceAll("T"," ").replaceAll("\\+0000","");
		return asDate(LocalDateTime.parse(dateStr, yyyymmddhhmmssFormatter));
	}

	/**
	 * Date 转 String 不带时间
	 * @param date
	 * @return
	 */
	public static String dateFormat(Date date){
		return yyyymmddFormatter.format(asLocalDate(date));
	}
	/**
	 * DateTime 转String 带时间
	 * @param date
	 * @return
	 */
	public static String dateTimeFormat(Date date){
		return yyyymmddhhmmssFormatter.format(asLocalDateTime(date));
	}

	/**
	 * DateTime 转String 精确到毫秒
	 * @param date
	 * @return
	 */
	public static String dateTimeMillecondFormat(Date date){
		return yyyymmddhhmmssSSSFormatter.format(asLocalDateTime(date));
	}


	/**
	 * DateTime 转 date 只有日期部分，时间为0点
	 * @param date
	 * @return
	 */
	public static Date dateTimeToDate(Date date){
		return asDate(asLocalDate(date));

	}

	private static Date asDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

	private static Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

	private static LocalDate asLocalDate(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
    }

	private static LocalDateTime asLocalDateTime(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

	/**
	 *
	 * <p>Description: 本地时间转化为UTC时间</p>
	 * @param localTime
	 * @return
	 * @author wgs
	 * @date  2018年10月19日 下午2:23:43
	 *
	 */
	public static Date localToUTC(String localTime) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date localDate= null;
		try {
			localDate = sdf.parse(localTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		long localTimeInMillis=localDate.getTime();
		/** long时间转换成Calendar */
		Calendar calendar= Calendar.getInstance();
		calendar.setTimeInMillis(localTimeInMillis);
		/** 取得时间偏移量 */
		int zoneOffset = calendar.get(java.util.Calendar.ZONE_OFFSET);
		/** 取得夏令时差 */
		int dstOffset = calendar.get(java.util.Calendar.DST_OFFSET);
		/** 从本地时间里扣除这些差量，即可以取得UTC时间*/
		calendar.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
		/** 取得的时间就是UTC标准时间 */
		Date utcDate=new Date(calendar.getTimeInMillis());
		return utcDate;
	}

	/**
	 *
	 * <p>Description:UTC时间转化为本地时间 </p>
	 * @param utcTime
	 * @return
	 * @author wgs
	 * @date  2018年10月19日 下午2:23:24
	 *
	 */
	public static Date utcToLocal(String utcTime){
		utcTime = utcTime.replaceAll("T"," ").replaceAll("\\+0000","");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
		Date utcDate = null;
		try {
			utcDate = sdf.parse(utcTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		sdf.setTimeZone(TimeZone.getDefault());
		Date locatlDate = null;
		String localTime = sdf.format(utcDate.getTime());
		try {
			locatlDate = sdf.parse(localTime);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return locatlDate;
	}


}
